<template>
  <div class="upload" @paste="onPaste">
    <slot></slot>
    <slot name="upload-list">
      <!-- 文件上传 -->
      <div class="upload-list upload-list-file" v-if="type == 'file' && files.length">
        <div class="upload-item upload-item-file" v-for="(item, index) in files" :key="index">
          <div class="upload-item-close" @click.prevent="handleDel(index)"></div>
          <a class="upload-item-title" :href="item[dataName]" target="_blank">{{
            item.originalName || item[dataName]
          }}</a>
          <div class="upload-progress-bar" v-if="item.status && item.status != 'success'">
            <div class="upload-percentage" :style="{ width: item.percentage + '%' }"
              :class="{ 'upload-percentage-uploading': item.status == 'uploading', 'upload-percentage-success': item.status == 'success', 'upload-percentage-fail': item.status == 'fail' }">
            </div>
          </div>
          <div class="upload-status" v-if="item.status != 'success'">
            <span v-if="item.status == 'uploading'">{{ item.percentage }}%</span>
            <span v-if="item.status == 'success'">上传完成</span>
            <span v-if="item.status == 'fail'">上传失败</span>
          </div>
        </div>
      </div>
      <!-- 多图上传 -->
      <div class="upload-list upload-list-image" v-if="type == 'images' && files.length">
        <a v-for="(item, index) in files" class="upload-item upload-item-image" :href="item[dataName]" target="_blank"
          :key="index">
          <div class="upload-image">
            <img :src="item[dataName] || item.file" />
          </div>
          <div class="upload-uploading" v-if="item.status && item.status != 'success'">
            <div class="upload-progress-bar" v-if="item.status">
              <div class="upload-percentage" :style="{ width: item.percentage + '%' }"
                :class="{ 'upload-percentage-uploading': item.status == 'uploading', 'upload-percentage-success': item.status == 'success', 'upload-percentage-fail': item.status == 'fail' }">
              </div>
            </div>
            <div class="upload-status">
              <span v-if="item.status == 'uploading'">正在上传</span>
              <span v-if="item.status == 'success'">上传完成</span>
              <span v-if="item.status == 'fail'">上传失败</span>
            </div>
          </div>

          <div class="upload-item-close" @click.prevent="handleDel(index)"></div>
        </a>
      </div>
      <!-- 单图上传 -->
      <div class="upload-list upload-list-image" v-if="type == 'image' && files.length">
        <template v-if="files">
          <a v-for="(item, index) in files" class="upload-item upload-item-image" :key="index" style="margin-top: 0"
            :href="item[dataName] || item.file" target="_blank">
            <div class="upload-image">
              <img :src="item[dataName]" />
              <!-- <div class="upload-item-edit">编辑</div> -->
            </div>
            <div class="upload-uploading" v-if="item.status && item.status != 'success'">
              <div class="upload-progress-bar" v-if="item.status">
                <div class="upload-percentage" :style="{ width: item.percentage + '%' }"
                  :class="{ 'upload-percentage-uploading': item.status == 'uploading', 'upload-percentage-success': item.status == 'success', 'upload-percentage-fail': item.status == 'fail' }">
                </div>
              </div>
              <div class="upload-status">
                <span v-if="item.status == 'uploading'">正在上传</span>
                <span v-if="item.status == 'success'">上传完成</span>
                <span v-if="item.status == 'fail'">上传失败</span>
              </div>
            </div>
            <div class="upload-item-close" @click.prevent="handleDel(index)"></div>
          </a>
        </template>
        <template v-else>
          <a class="upload-item upload-item-image" style="margin-top: 0">
            <div class="upload-image upload-image-add"></div>
          </a>
        </template>
      </div>

      <!-- 视频上传 -->
      <div class="upload-list upload-list-image" v-if="type == 'video' && files.length">
        <template v-if="files">
          <a v-for="(item, index) in files" class="upload-item upload-item-image" :key="index" style="margin-top: 0"
            :href="item[dataName] || item.file" target="_blank">
            <div class="upload-image">
              <video muted autoplay loop :src="item[dataName] || item.file"></video>
            </div>
            <div class="upload-uploading" v-if="item.status && item.status != 'success'">
              <div class="upload-progress-bar" v-if="item.status">
                <div class="upload-percentage" :style="{ width: item.percentage + '%' }"
                  :class="{ 'upload-percentage-uploading': item.status == 'uploading', 'upload-percentage-success': item.status == 'success', 'upload-percentage-fail': item.status == 'fail' }">
                </div>
              </div>
              <div class="upload-status">
                <span v-if="item.status == 'uploading'">正在上传</span>
                <span v-if="item.status == 'success'">上传完成</span>
                <span v-if="item.status == 'fail'">上传失败</span>
              </div>
            </div>
            <div class="upload-item-close" @click.prevent="handleDel(index)"></div>
          </a>
        </template>
        <template v-else>
          <a class="upload-item upload-item-image" style="margin-top: 0">
            <div class="upload-image upload-image-add"></div>
          </a>
        </template>
      </div>
    </slot>
    <InputFile v-model="files" :url="url" :inputAttr="input" :beforeUpload="beforeUpload" :uploadSuccess="uploadSuccess"
      :limit="limit" class="upload-header" ref="input">
      <template v-slot:input-before>
        <slot name="input-before"></slot>
      </template>
      <template v-slot:input>
        <slot name="input"></slot>
      </template>
      <template v-slot:input-after>
        <slot name="input-after"></slot>
      </template>
    </InputFile>
  </div>
</template>

<script>
import InputFile from './input-file/InputFile.vue'

export default {
  name: 'JaxUpload',
  inheritAttrs: false,
  components: {
    InputFile,
  },
  props: {
    modelValue: null,

    type: {
      type: String,
      default: 'image',
    },

    // 上传前
    beforeUpload: Function,

    // 上传成功
    uploadSuccess: Function,

    // 数量限制
    limit: Number,

    url: {
      type: String,
    },

    // 后台接口数据中的url命名
    dataName: {
      type: String,
      default: 'url',
    },

    // 按原始数据返回
    rawData: {
      default: false,
    },

    // 原生input属性
    inputAttr: Object,
  },
  data() {
    return {
      input: {},
      files: [],
    }
  },
  created() {
    this.init()
  },
  watch: {
    // 选择切换式上传时，切换后不能动态的选择设置的文件类型
    inputAttr() {
      this.init()
    },
    type() {
      this.init()
    },
    modelValue() {
      this.getFiles()
    },
    files() {
      let value

      if (!this.rawData) {
        if (['image', 'video', 'file'].includes(this.type)) {
          value = this.files.length ? this.files[0][this.dataName] : ''
        } else {
          value = this.files.map((item) => {
            return item[this.dataName]
          })
        }
      }

      this.$emit('update:modelValue', value)
    },
  },
  methods: {
    init() {
      const input = {}

      if (this.type == 'image') {
        input.accept = 'image/*'
      } else if (this.type == 'images') {
        input.accept = 'image/*'
        input.multiple = true
      } else if (this.type == 'files') {
      } else if (this.type == 'video') {
        // input.accept = '.mp4'
        input.accept = 'video/*'
      }

      this.input = {
        ...input,
        ...this.inputAttr,
      }

      this.getFiles()
    },
    getFiles() {
      let newFiles = this.modelValue || []

      if (!this.rawData) {
        if (typeof newFiles == 'string') {
          newFiles = newFiles.split(',')
        }

        newFiles = newFiles.map((file) => {
          return {
            [this.dataName]: file,
          }
        })
      }

      // 只需要在初始化时赋值，之后files由InputFile组件控制
      if (newFiles.length != this.files.length) {
        if (newFiles.length && newFiles[0][this.dataName]) {
          this.files = newFiles
        } else if (newFiles.length == 0) {
          this.files = newFiles
        }
      } else if (newFiles.length && newFiles[0][this.dataName] && newFiles[0][this.dataName] != this.files[0]?.[this.dataName]) {
        this.files = newFiles
      }
    },

    // 手动清空数据【强制防止数据缓存】
    clear() {
      this.files = []
    },

    handleDel(index) {
      const files = [...this.files]

      files.splice(index, 1)

      this.files = files
    },
    onPaste(e) {
      e.preventDefault()

      if (e.clipboardData.types == 'text/html,Files') {
        const item = e.clipboardData.items[1]
        const file = item.getAsFile()

        this.$refs.input.upload([file])
      } else if (e.clipboardData.types == 'Files') {
        const item = e.clipboardData.items[0]
        const file = item.getAsFile()

        this.$refs.input.upload([file])
      }
    },
  },
}
</script>

<style scoped lang="scss">
.upload-list {
  margin-bottom: 15px;
}

.upload-list-file {
  display: flex;
  flex-flow: wrap;
}

.upload-item {
  position: relative;
  margin-right: 15px;
  margin-top: 15px;
  overflow: initial;
}

.upload-item-file {
  width: 279px;
  height: 82px;
  border-radius: 8px;
  border: solid 1px #eef2f9;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  text-align: center;

  // &:nth-child(3n){
  //     margin-right: 0;
  // }

  .upload-item-title {
    width: 194px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #758196;
    margin-bottom: 5px;
  }
}

.upload-list-image {
  // max-width: 889px;
  display: flex;
  flex-flow: wrap;
}

.upload-item-image {
  display: block;

  .upload-image {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    overflow: hidden;
    width: 114px;
    height: 114px;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    position: relative;
    overflow: hidden;

    img {
      max-height: 100%;
      max-width: initial;
    }
  }

  .upload-item-edit {
    position: absolute;
    background: rgba(0, 0, 0, 0.5);
    bottom: 0;
    left: 0;
    width: 100%;
    text-align: center;
    color: #fff;
    line-height: 23px;
  }

  .upload-image-add {
    position: relative;

    &::before {
      content: "";
      position: absolute;
      left: 50%;
      top: 50%;
      width: 30px;
      border-top: 3px solid #a99b9d;
      border-radius: 3px;
      margin-left: -15px;
      margin-top: -1.5px;
    }

    &::after {
      content: "";
      position: absolute;
      left: 50%;
      top: 50%;
      height: 30px;
      border-left: 3px solid #a99b9d;
      border-radius: 3px;
      margin-top: -15px;
      margin-left: -1.5px;
    }
  }
}

.upload-progress-bar {
  width: 202px;
  height: 8px;
  background-color: #eef2f9;
  border-radius: 4px;
  border: solid 1px #cfd5e0;
  position: relative;
}

.upload-status {
  font-size: 12px;
  margin-top: 5px;
}

.upload-percentage {
  border-radius: 3px;
  width: 10%;
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  height: 6px;
  transition: all 0.3s;
}

.upload-percentage-uploading {
  background-color: #2280d9;
}

.upload-percentage-success {
  background-color: #37c9aa;
}

.upload-percentage-fail {
  background-color: #f60813;
}

.upload-item-close {
  background-image: url();
  background-repeat: no-repeat;
  background-size: cover;
  width: 28px;
  height: 28px;
  position: absolute;
  right: -14px;
  top: -14px;
  z-index: 1;
}

.upload-uploading {
  position: absolute;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.4);
  padding: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  top: 0;
  left: 0;
  border-radius: 8px;

  .upload-progress-bar {
    width: 100%;
  }

  .upload-status {
    color: #fff;
  }
}
</style>
